package ai;

import item.mod.Mod;
import item.ship.Ship;
import item.weapon.DamageType;
import item.weapon.Weapon;

import java.util.Collection;

public class AutoAttack {
	
	public static void auto(Ship attacker, Collection<Ship> defenders) {
		while(AA(attacker, defenders)) {}
	}
	
	private static boolean AA(Ship attacker, Collection<Ship> defenders) {
		Ship toAttack = null;
		for(Ship s : defenders) {
			if(s.getShields() == 0) {
				toAttack = s;
			}// checks if there are any ships without shields
		}//loops through all ships
		if(toAttack == null) {
			int leastShields = Integer.MAX_VALUE;
			if(!hasMissile(attacker)) {
				for(Ship s: defenders) {
					int shield = s.getShields();
					for(Mod m: s.getMod()) 
					{
						shield = (int) (shield * m.getShieldMult() * m.getDefensiveMult());
					}//calculates the approximate shield
					if(shield < leastShields)
						leastShields = shield;
				}//finds out which ship has the least approximate shields
				for(Ship s: defenders) {
					int shield = s.getShields();
					for(Mod m: s.getMod()) 
					{
						shield = (int) (shield * m.getShieldMult() * m.getDefensiveMult());
					}//calculates the shield value per ship
					if(shield == leastShields)
						toAttack = s;
				}//adds the ships with the least approximate shields into the list of ships to attack
				
				int maxDamage = 0;
				
				for(Weapon w : attacker.getWeapon()) {
					int damage = (int) ((w.damage * w.numAttacks * w.hitRate * w.type.shieldMultiplier) / (w.actionPoint * 1.0));
					for(Mod m : attacker.getMod()) {
						damage = (int) (damage * m.getDamageMult());
						switch(w.type) {
							case LASER:
								damage = (int) (damage * m.getLaserMult());
								break;
							case MISSILE:
								damage = (int) (damage * m.getMissileMult());
								break;
							case ARMOR_PENETRATING:
								damage = (int) (damage * m.getArmorpenMult());
								break;
							case PLASMA:
								damage = (int) (damage * m.getPlasmaMult());
								break;
							default:
								break;
						}//specific multipliers
					}//applies mod multipliers
					if(damage > maxDamage) {
						maxDamage = damage;
					}//fires on the ship
				}//checks which ship has the least shields
				
				for(Weapon w : attacker.getWeapon()) {
					int damage = (int) (w.damage * w.numAttacks * w.hitRate * w.type.shieldMultiplier);
					for(Mod m : attacker.getMod()) {
						damage = (int) (damage * m.getDamageMult());
						switch(w.type) {
							case LASER:
								damage = (int) (damage * m.getLaserMult());
								break;
							case MISSILE:
								damage = (int) (damage * m.getMissileMult());
								break;
							case ARMOR_PENETRATING:
								damage = (int) (damage * m.getArmorpenMult());
								break;
							case PLASMA:
								damage = (int) (damage * m.getPlasmaMult());
								break;
							default:
								break;
						}//specific multipliers
					}//applies mod multipliers
					if(damage == maxDamage) {
						if(attacker.attack(w, toAttack)) {
							return true;
						}
					}//fires on the ship
				}//checks which ship has the least shields
				
				return false;
			} //checks for missiles
			
		} // if the ship has shields
		else
		{
			int leastHull = 0;
			for(Ship s: defenders) {
				int hull = s.getShields();
				for(Mod m: s.getMod()) 
				{
					hull = (int) (hull * m.getHullMult() * m.getDefensiveMult());
				}//calculates the approximate hull
				if(hull < leastHull)
					leastHull = hull;
			}//finds out which ship has the least approximate hull
			for(Ship s: defenders) {
				int hull = s.getShields();
				for(Mod m: s.getMod()) 
				{
					hull = (int) (hull * m.getHullMult() * m.getDefensiveMult());
				}//calculates the shield value per ship
				if(hull == leastHull)
					toAttack = s;
			}//adds the ships with the least approximate shields into the list of ships to attack
		
			int maxDamage = 0;
			
			for(Weapon w : attacker.getWeapon()) {
				int damage = (int) ((w.damage * w.numAttacks * w.hitRate * w.type.hullMultiplier) / (w.actionPoint * 1.0));
				for(Mod m : attacker.getMod()) {
					damage = (int) (damage * m.getDamageMult());
					switch(w.type) {
						case LASER:
							damage = (int) (damage * m.getLaserMult());
							break;
						case MISSILE:
							damage = (int) (damage * m.getMissileMult());
							break;
						case ARMOR_PENETRATING:
							damage = (int) (damage * m.getArmorpenMult());
							break;
						case PLASMA:
							damage = (int) (damage * m.getPlasmaMult());
							break;
						default:
							break;
					}//specific multipliers
				}//applies mod multipliers
					if(damage > maxDamage)
						maxDamage = damage;
			}//checks which weapon does the most damage to hull
			
			for(Weapon w : attacker.getWeapon()) {
				int damage = (int) ((w.damage * w.numAttacks * w.hitRate * w.type.hullMultiplier) / (w.actionPoint * 1.0));
				for(Mod m : attacker.getMod()) {
					damage = (int) (damage * m.getDamageMult());
					switch(w.type) {
						case LASER:
							damage = (int) (damage * m.getLaserMult());
							break;
						case MISSILE:
							damage = (int) (damage * m.getMissileMult());
							break;
						case ARMOR_PENETRATING:
							damage = (int) (damage * m.getArmorpenMult());
							break;
						case PLASMA:
							damage = (int) (damage * m.getPlasmaMult());
							break;
						default:
							break;
					}//specific multipliers
				}//applies mod multipliers
					if(damage == maxDamage)
						if(attacker.attack(w, toAttack)) {
							return true;
						}
			}//checks which ship has the least shields
		
		}//picks a ship based on damage dealt on a percentage basis
		
		return false;
		
	}//gets a ship to attack another ship based on stats;
	
	//helper method to detect missiles
	
	private static boolean hasMissile(Ship attacker) {
		for(Weapon wep : attacker.getWeapon()) {
			if(wep.type.equals(DamageType.MISSILE)) {
				return true;
			}//there is a missile weapon
		}//checks the weapons list of the attacking ship
		return false;
	}//end of helper method hasMissile
	
	//helper method to use drones
	
	
}//end of class AutoAttack
